/**
 * 请求防抖和节流实现类
 * @Author TAO 1755885716@qq.com
 * @Date 2024/9/25
 */
export default class ThorttleAndDebounce {
	#debounceApi = {};//防抖api
	#throttleApi = {};//节流api
	// #axios = null
	/**
	 * 构造器
	 * @param {*} inst axios实例
	 */
	constructor(inst){
		// this.#axios=inst
	}
	/**
	 * 创建cancel token
	 * @returns CancelToken.source()
	 */
	// getToken(){
	// 	const CancelToken = this.#axios.CancelToken;
	// 	const source = CancelToken.source();
	// 	return source
	// }
	/**
	 * 防抖实现  只有当等待的时间内没有再触发事件，才执行函数。
	 * @param {*} config axiox Config
	 * @param {*} source CancelToken.source()
	 * @returns Promise
	 */
	debounce(config){
		return new Promise(resolve=>{
			let debounceKey = config.debounceKey||config.url
			// 找到已存在的它，并结束它的申明，然后自己替换它进入列队
			if(this.#debounceApi[debounceKey]){
				let {timeIndex,callback} = this.#debounceApi[debounceKey]
				callback(false)
				clearTimeout(timeIndex)
				delete this.#debounceApi[debounceKey]
			}
			this.#debounceApi[debounceKey] = {
				debounceKey,
				debounceTime: config.debounceTime,
				config,
				timeTemp:new Date(),
				callback:resolve,
				timeIndex:setTimeout(()=>{
					resolve(true)
					delete this.#debounceApi[debounceKey]
				},config.debounceTime),
			}
		})
	}
	/**
	 * 节流实现  如果在指定的时间间隔内再次触发事件，则忽略这次触发。
	 * @param {*} config axiox Config
	 * @param {*} source CancelToken.source()
	 * @returns Promise
	 */
	throttle(config){
		return new Promise(resolve=>{
			let throttleKey = config.throttleKey||config.url
			if(this.#throttleApi[throttleKey]) return resolve(false)
			this.#throttleApi[throttleKey] = {
				throttleKey,
				throttleTime: config.throttleTime,
				config,
				timeTemp:new Date(),
			}
			setTimeout(()=>{
				delete this.#throttleApi[throttleKey]
			},config.throttleTime)
			resolve(true)
		})

	}
	/**
	 * 分发器
	 * @param {*} config axiox Config
	 * @returns true 允许执行  false 被优化掉
	 */
	async repetition(config){
		if(!config.debounceTime && !config.throttleTime) return true
		// 先节流 后防抖
		if(config.throttleTime && !await this.throttle(config)) return false
		if(config.debounceTime && !await this.debounce(config)) return false
		return true
	}
}
